﻿#region Copyright © 2008 by Christian Rodemeyer
// $HeadURL: http://rodemeyer.googlecode.com/svn/trunk/Rodemeyer/WPF/WpfHelper.cs $
// $Revision: 27 $
#endregion

using System;
using System.Reflection;
using System.Windows;
using System.Windows.Documents;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Rodemeyer.Wpf
{
    public static class WpfHelper
    {
        public static Uri GetAssemblyResourceUri(Assembly a, string path)
        {
            return new Uri("pack://application:,,,/" + a.GetName().Name + ";Component/" + path.TrimStart('/'));
        }

        public static Uri GetLocalResourceUri(string path)
        {
            return GetAssemblyResourceUri(Assembly.GetCallingAssembly(), path);
        }

        public static Point GetMousePosition()
        {
            Win32Point p;
            GetCursorPos(out p);
            return new Point(p.x, p.y);
        }

        [DllImport("user32.dll")]
        static extern bool GetCursorPos(out Win32Point point);
        [StructLayout(LayoutKind.Sequential)]
        struct Win32Point
        {
            public int x, y;
        }

        public static void SetWindowBounds(Window w, Rect bounds)
        {
            w.Left = bounds.Left;
            w.Width = bounds.Width;
            w.Top = bounds.Top;
            w.Height = bounds.Height; 
        }


        /// <summary>
        /// returns the actual bounds of a window in screen coordinates
        /// </summary>
        public static Rect GetWindowBounds(Window w)
        {
            return new Rect(w.Left, w.Top, w.ActualWidth > 0 ? w.ActualWidth : w.Width, w.ActualHeight > 0 ? w.ActualHeight : w.Height);
        }

        public static void MoveWindowUnderMouse(Window w, Vector offset)
        {
            if (w.IsLoaded)
            {
                InternalMoveWindowUnderMouse(w, offset);
            }
            else
            {
                w.WindowStartupLocation = WindowStartupLocation.Manual;
                w.Loaded += delegate { InternalMoveWindowUnderMouse(w, offset); };
            }
        }

        static void InternalMoveWindowUnderMouse(Window w, Vector offset)
        {
            Point p = WpfHelper.GetMousePosition();
            Rect r = GetWindowBounds(w);
            r.Location = p - offset;
            SetWindowBounds(w, ScreenHelper.MoveRectIntoWorkingArea(r));
        }

        public static void CenterWindowUnderMouse(Window w)
        {
            if (w.IsLoaded)
            {
                InternalMoveWindowUnderMouse(w, new Vector(w.ActualWidth / 2, w.ActualHeight / 2));
            }
            else
            {
                w.WindowStartupLocation = WindowStartupLocation.Manual;
                w.Loaded += delegate { InternalMoveWindowUnderMouse(w, new Vector(w.ActualWidth / 2, w.ActualHeight / 2)); };
            }
        }

        // This will be extension methods with C# 3.0

        #region FlowDocument related helpers

        public static string DocumentToText(FlowDocument doc)
        {
            return new TextRange(doc.ContentStart, doc.ContentEnd).Text;
        }

        public static FlowDocument TextToDocument(string text)
        {
            return new FlowDocument(new Paragraph(new Run(text)));
        }

        public static void LoadDocumentFromText(FlowDocument doc, Stream stream)
        {
            new TextRange(doc.ContentStart, doc.ContentEnd).Load(stream, DataFormats.Text);
        }

        public static void SaveDocumentAsText(FlowDocument doc, Stream stream)
        {
            (new TextRange(doc.ContentStart, doc.ContentEnd)).Save(stream, DataFormats.Text);
        }

        public static void LoadDocumentFromRtf(FlowDocument doc, Stream stream)
        {
            new TextRange(doc.ContentStart, doc.ContentEnd).Load(stream, DataFormats.Rtf);
        }

        public static void SaveDocumentAsRtf(FlowDocument doc, Stream stream)
        {
            (new TextRange(doc.ContentStart, doc.ContentEnd)).Save(stream, DataFormats.Rtf);
        }

        public static void LoadDocumentFromXaml(FlowDocument doc, Stream stream)
        {
            new TextRange(doc.ContentStart, doc.ContentEnd).Load(stream, DataFormats.Xaml);
        }

        public static void SaveDocumentAsXaml(FlowDocument doc, Stream stream)
        {
            (new TextRange(doc.ContentStart, doc.ContentEnd)).Save(stream, DataFormats.Xaml);
        }

        #endregion

    }
}
